﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

namespace ExcelConfig.helpers
{
    internal partial class helper
    {
        public static void ReadAllToMemory(Stream sr, Stream dst)
        {
            var buf = new byte[1024];
            int len = 1;
            while (sr.CanRead && len != 0) if ((len = sr.Read(buf, 0, 1024)) > 0) dst.Write(buf, 0, len);
            dst.Flush();
        }
        public static decimal parse_to_number(object obj)
        {
            if (obj is null) return 0;
            if (obj is string text)
            {
                if (decimal.TryParse(text, out decimal result)) return result;
            }
            else if (obj is decimal num) return num;
            else if (obj is int o_int) return o_int;
            else if (obj is double o_double) return (decimal)o_double;
            else if (obj is float o_float) return (decimal)o_float;
            else if (obj is long o_long) return o_long;
            else if (obj != null)
            {
                return (decimal)obj;
            }

            return 0;
        }
        public static string parse_to_text(object obj)
        {
            if (obj is null) return string.Empty;
            if (obj is string text) return text;
            else return obj.ToString();
        }
        public static List<T> to_list<T>(IEnumerator<T> enumer)
        {
            if (enumer == null) return null;
            var rlt = new List<T>();
            while (enumer.MoveNext()) rlt.Add(enumer.Current);
            return rlt;
        }
        public static List<T> to_list<T>(IEnumerator enumer)
        {
            var rlt = new List<T>();
            while (enumer.MoveNext()) if (enumer.Current is T t) rlt.Add(t);
            return rlt;
        }
        public delegate bool Pduan<T>(T t);
        public static T SingleOrDefault<T>(IEnumerator enumer, Pduan<T> func)
        {
            while (enumer.MoveNext()) if (enumer.Current is T t && func(t)) return t;
            return default;
        }
        public static T SingleOrDefault<T>(T[] arr, Pduan<T> func)
        {
            for(int i = 0; i < arr.Length; i++) if(func(arr[i])) return arr[i];
            return default;
        }
        public static T SingleOrDefault<T>(IEnumerator enumer)
        {
            while (enumer.MoveNext()) if (enumer.Current is T t) return t;
            return default;
        }
        public delegate uint SelectOrderId<in T>(T x);
        public delegate int SelectOrderId_int<in T>(T x);
        public static IEnumerable<T> OrderBy<T>(IList<T> arr, SelectOrderId<T> select)
        {
            var sorted = new ulong[arr.Count];
            var i = 0;
            foreach (var x in arr) sorted[i] = ((uint)i++ | ((ulong)select(x) << 32));
            Array.Sort(sorted);
            for (i = 0; i < sorted.Length; i++)
                yield return arr[(int)(sorted[i] & 0xffffffff)];
        }
        public static uint Max<T>(IList<T> arr, SelectOrderId<T> select)
        {
            if (arr.Count == 0) return default;
            var max_item = select(arr[0]);
            foreach (var item in arr) if (max_item <  select(item)) max_item = select(item);
            return max_item;
        }
        public static int Max<T>(IList<T> arr, SelectOrderId_int<T> select)
        {
            if (arr.Count == 0) return default;
            var max_item = select(arr[0]);
            foreach (var item in arr) if (max_item < select(item)) max_item = select(item);
            return max_item;
        }
    }
}
